package register

import (
	"fmt"
	"github.com/nacos-group/nacos-sdk-go/v2/clients"
	"github.com/nacos-group/nacos-sdk-go/v2/clients/naming_client"
	"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
	"github.com/nacos-group/nacos-sdk-go/v2/vo"
	"go-proxy/common"
	"go-proxy/config"
)

type NacosService struct {
	client naming_client.INamingClient
}

func NewNacosService() *NacosService {
	return &NacosService{}
}

func (n *NacosService) InitService(service *config.Service) error {
	nacosConfig := service.Nacos
	clientConfig := constant.ClientConfig{
		NamespaceId:         "", // 如果需要支持多namespace，我们可以创建多个client,它们有不同的NamespaceId。当namespace是public时，此处填空字符串。
		TimeoutMs:           5000,
		NotLoadCacheAtStart: true,
		LogDir:              "./log/nacos/log",
		CacheDir:            "./log/nacos/cache",
		LogLevel:            "debug",
	}

	if len(nacosConfig.NamespaceId) > 0 {
		clientConfig.NamespaceId = nacosConfig.NamespaceId
	}
	if len(nacosConfig.Username) > 0 {
		clientConfig.Username = nacosConfig.Username
	}
	if len(nacosConfig.Password) > 0 {
		clientConfig.Password = nacosConfig.Password
	}

	serverConfig := constant.ServerConfig{
		IpAddr:      "127.0.0.1",
		ContextPath: "/nacos",
		Port:        8848,
		Scheme:      "http",
	}

	if len(nacosConfig.Address) > 0 {
		serverConfig.IpAddr = nacosConfig.Address
	}
	if nacosConfig.Port > 0 {
		serverConfig.Port = nacosConfig.Port
	}
	if len(nacosConfig.ContextPath) > 0 {
		serverConfig.ContextPath = nacosConfig.ContextPath
	}
	if len(nacosConfig.Scheme) > 0 {
		serverConfig.Scheme = nacosConfig.Scheme
	}

	serverConfigs := []constant.ServerConfig{
		serverConfig,
	}

	// 创建服务发现客户端
	namingClient, err := clients.NewNamingClient(
		vo.NacosClientParam{
			ClientConfig:  &clientConfig,
			ServerConfigs: serverConfigs,
		},
	)
	if err != nil {
		return err
	}

	healthy := namingClient.ServerHealthy()
	common.LogDebug("nacos client init healthy=", healthy)

	n.client = namingClient
	return nil
}

func (n *NacosService) GetInstances(service *config.Service, route *config.Route) ([]*InstanceInfo, error) {
	nacosConfig := service.Nacos
	param := vo.GetServiceParam{
		ServiceName: route.InstanceName,
		GroupName:   "DEFAULT_GROUP",
	}

	if len(nacosConfig.GroupName) > 0 {
		param.GroupName = nacosConfig.GroupName
	}
	if len(nacosConfig.Clusters) > 0 {
		param.Clusters = nacosConfig.Clusters
	}

	serviceInfo, err := n.client.GetService(param)
	if err != nil {
		common.LogErrorf("get nacos service=%s register=%s instances error:%v", service.Name, route.InstanceName, err)
		return nil, err
	}

	instances := make([]*InstanceInfo, 0)
	for _, instance := range serviceInfo.Hosts {
		instances = append(instances, &InstanceInfo{
			Address: fmt.Sprintf("http://%s:%d", instance.Ip, instance.Port),
			Port:    instance.Port,
			Host:    instance.Ip,
		})
	}
	common.LogDebugF("get nacos instances:%v", instances)
	return instances, nil
}
